import { Avatar, Button, Divider, Drawer, Input, Popover, Progress, Spin, Switch, Tabs, Upload } from "@arco-design/web-react";
import React, { Fragment, useCallback, useContext, useEffect, useLayoutEffect, useRef, useState } from "react";
import { IconButton } from "../../../components/IconButton";
import { IconClose, IconDown, IconEdit, IconMinus, IconMore, IconMoreVertical, IconPlus, IconQuote, IconRight, IconSearch, IconUp } from "@arco-design/web-react/icon";
import { MessageItem } from "../components/MessageItem";
import { InputBox } from "../components/input_box";
import { MessageType, ConversationType, MessageState } from "../../../domain/im/entity";
import { useDispatch, useSelector } from "react-redux";
import { addMessageState, openMessage, updateMessageImage } from "../../../store/features/message";
import { UserModelElement } from "../../friend/components/user_model";
import TabPane from "@arco-design/web-react/es/Tabs/tab-pane";

import './index.css';
import http, { getFile } from "../../../http"
import { UserInfo } from "../../../domain/user";
import { GroupInfo } from "../../../domain/group";
import { clearUnreadCount, fetchConversationList } from "../../../store/features/conversation";
import { fetchGroupInfo } from "../../../store/features/group";

import MBProtocalFactory from '../../../sdk/module/mb_constants'
import IMSDK from '../../../sdk'



import uuid from "../../../sdk/module/uuid";
import { fetchGroupMemberInfo } from "../../../store/features/group_member";
import axios from "axios";
import { generateThumbnail } from "../util/image_thumbnail";
import { uploadFile } from "../util/upload";
import { getVideoThumbnail } from "../util/video_thumbnail";
import { PullRefresh } from "@arco-design/mobile-react";
import { LeoAvatar } from "../../../components/leo_Avatar";
import { formatTimestampWithWeekday } from "../util/times";
import { DrawerGroupInfo } from "../components/drawer_group";
import { ChatContext } from "..";
import { UseIsGroupUser } from "../hook/is_group_user";
import { userInfo } from "os";
import { addUser } from "../../../store/features/otherUser";









export const ChatContent: React.FC<any> = ({ topRef }) => {

    // 会话列表 当前选中的会话
    const { list, current } = useSelector((state: any) => state.conversation.value);
    // 当前登录的用户
    const { user } = useSelector((state: any) => state.user.value);
    // 消息记录
    const messages = useSelector((state: any) => state.message.value);
    const groupMap = useSelector((state: any) => state.group.value);
    const users = useSelector((state: any) => state.friend.value.users);

    // 获取当前群资料
    let currentGroup = list[current] ? groupMap[list[current].targetId] : {};



    // 控制显示 群组资料还是用户资料
    const [visible, setVisible] = useState(false);
    // const [visibleGroup, setVisibleGroupInfo] = useState(false);
    const refWrapper = useRef(null);

    
    const {groupDrawerVisible, setGroupDrawerVisible} = useContext(ChatContext);








    const { showInput } = UseIsGroupUser(list[current]);



    useEffect(() => {
        if (groupDrawerVisible) {
            setGroupDrawerVisible(false);
        }
        if (visible) {
            setVisible(false);
        }

    }, [current])

    const clickMore = async () => {
        if (list[current].type == ConversationType.private) {
            setVisible(true);
        } else {
            setGroupDrawerVisible(true)
        }
    }





    return <>
        <div ref={refWrapper} className="flex flex-row flex-1 min-w-[790px] relative">
            {
                list[current] && list[current].type == ConversationType.group &&
                <DrawerGroupInfo conversation={list[current]} topRef={topRef} targetId={list[current].targetId} visibleGroup={groupDrawerVisible} refWrapper={refWrapper} setVisibleGroupInfo={setGroupDrawerVisible} />
            }

            <div className="flex flex-col flex-1 w-full h-full" >
                {

                    list[current] && <div className="flex flex-row justify-between pl-[24px] pr-[16px] items-center h-[66px] w-full  border-b border-b-[#E6EBF5]">
                        <div className='text-[16px]'>
                            <LeoAvatar userPortrait={list[current].portrait} userName={list[current].userName}></LeoAvatar>
                            <span className='ml-[16px]'>{list[current].remark ? list[current].remark :list[current].userName } </span>
                        </div>
                        {
                            showInput && <div className='flex space-x-4'>
                                <IconButton onClick={clickMore} icon={<IconMore />}></IconButton>
                            </div>
                        }
                    </div>
                }
                {
                    list[current] &&
                    <div className=" w-full flex flex-col flex-grow">
                        {
                            <ChatMessageList list={(messages && list[current]) ? messages[list[current].targetId] : []} conversation={list[current]}></ChatMessageList>
                        }
                    </div>
                }
            </div>
        </div >

    </>
}




const ChatMessageList: React.FC<{ list: any[], conversation: any }> = ({ list, conversation }) => {
    const [loading, setLoading] = useState(false);
    const [hasMore, setHasMore] = useState(true);
    const listRef = useRef<any>(null);
    const [shouldScrollToBottom, setShouldScrollToBottom] = useState(true);
    const [scrollPosition, setScrollPosition] = useState<any>(0);
    const dispatch = useDispatch();


    const [messages, setMessages] = useState<any>([]);


    const groupMember = useSelector((state: any) => state.groupMember.value);

    const otherUsers = useSelector((state: any) => state.otherUser.value.users);

    useEffect(() => {
        if (conversation.type == ConversationType.group && conversation && list) {
            if (list.length > 0) {
                let newList: any = [];
                for (let message of list) {
                    if (message.from != '0') {
                        if (groupMember[conversation.targetId]) {
                            let findUser = groupMember[conversation.targetId].find((item: any) => item.userId == message.from);
                            if (findUser) {
                                newList.push({...message, userInfo: findUser});
                            }else{
                                let findUser = otherUsers.find((item: any) => item.userId == message.from);
                                if(findUser){
                                    newList.push({...message,userInfo: findUser });
                                }else{
                                    dispatch(addUser(message.from));
                                }
                               
                            }
                        }
                    } else {
                        newList.push(message);
                    }
                }
                setMessages(newList);
            }
        } else if(conversation.type == ConversationType.private && conversation && list){

            if(list.length > 0){
                let newList: any = [];
                for (let message of list) {

                }
            }
            setMessages(list);
        }
        else {
            setMessages(list);
        }

    }, [list,otherUsers])


    useEffect(() => {
        setShouldScrollToBottom(true);
    }, []);


    useEffect(() => {
        setScrollPosition(0);
        setShouldScrollToBottom(true)
    }, [conversation])


    const handleScroll = useCallback(() => {
        const listElement = listRef.current;
        if (listElement) {
            const { scrollTop, scrollHeight, clientHeight } = listElement;
            if (scrollTop <= 5 && hasMore && !loading) {
                setScrollPosition(scrollHeight);
                loadMoreMessages();
            }
        }
    }, [hasMore, loading, messages]);


    const loadMoreMessages = async () => {
        if (messages) {
            setLoading(true);
            messages.length == 0 ? await fetchdata() : await fetchdata(messages[0].timestamp);
            setLoading(false);
            setShouldScrollToBottom(false); // 加载更多后不自动滚动到底部
        }
    };




    useEffect(() => {
        const listElement = listRef.current;
        if (listElement) {
            listElement.addEventListener('scroll', handleScroll);
            return () => {
                if (listElement) {
                    listElement.removeEventListener('scroll', handleScroll);
                }
            };
        }
    }, [handleScroll, messages, hasMore]);

    useEffect(() => {
        const listElement = listRef.current;
        if (listElement && shouldScrollToBottom && scrollPosition == 0) {
            setTimeout(() => {
                listElement.scrollTop = listElement.scrollHeight;
                console.log(listElement.scrollHeight, "---");
            }, 50); // 立即执行的任务，等待浏览器重绘完成后执行
            console.log(listElement.scrollHeight)
        } else if (listElement && !shouldScrollToBottom && scrollPosition > 0) {
            listElement.scrollTop = listElement.scrollHeight - scrollPosition;
        }
    }, [messages, shouldScrollToBottom, scrollPosition, handleScroll, hasMore]);




    useLayoutEffect(() => {
        const listElement = listRef.current;
        listElement.scrollTop = listElement.scrollHeight;

    }, [])


    const fetchdata = async (timestamp?: any) => {
        let url = timestamp ? `/message/list?targetId=${conversation.targetId}&timestamp=${list[0].timestamp}` : `/message/list?targetId=${conversation.targetId}`;
        const response = await http.get(url)

        if (response.data) {
            if (response.data.length > 0) {
                const targetId = conversation.targetId;
                const listCopy = list.slice(); // 创建一个浅拷贝
                const reversedList = listCopy.reverse();
                const messages = [...reversedList, ...response.data,];
                dispatch(openMessage({ targetId, messages: messages }));
                setHasMore(true);
            } else {
                setHasMore(false);
            }

        }

    }


    const { list: conversations, current } = useSelector((state: any) => state.conversation.value);


    const addMessage = async (text: any, typeu: MessageType, file?: File) => {
        setScrollPosition(0);
        setShouldScrollToBottom(true)
        dispatch(clearUnreadCount({ targetId: conversations[current].targetId }))
        if (IMSDK.getLoginInfo().loginUserId != null) {
            let dataContent = "";
            if (typeu == MessageType.TxtMsg) {
                dataContent = JSON.stringify({
                    content: text
                });
            }

            if (typeu == MessageType.ImgMsg) {
                const { base64edData, originalWidth, originalHeight } = await generateThumbnail(file!);
                dataContent = JSON.stringify({
                    base64edData, originalWidth, originalHeight,
                });
            }

            if (typeu == MessageType.SightMsg) {
                const { base64edData, duration, originalHeight, originalWidth } = await getVideoThumbnail(file!);
                dataContent = JSON.stringify({
                    base64edData, originalWidth, originalHeight, duration
                });
            }


            if (typeu == MessageType.FileMsg) {
                dataContent = JSON.stringify({
                    size: file?.size,
                    name: file?.name,
                    type: file?.type,
                });
            }

            const to = conversations[current].type == ConversationType.group ? "0" : conversations[current].targetId;

            let p: any = MBProtocalFactory.createCommonData({
                dataContent,
                from: IMSDK.getLoginInfo().loginUserId,
                fp: uuid.v1(),
                QoS: true,
                to: to,
                typeu: typeu
            });

            if (conversations[current].type == ConversationType.group) {
                p.dataContent = JSON.stringify(
                    {
                        ...JSON.parse(p.dataContent),
                        groupId: conversations[current].targetId
                    }
                )
            }

    
            dispatch(addMessageState({
                targetId: `${conversations[current].targetId}`, message: {
                    ...p,
                    timestamp: new Date().getTime(),
                    state: MessageState.sending
                }
            }))


            if (typeu == MessageType.ImgMsg || typeu == MessageType.SightMsg || typeu == MessageType.FileMsg) {
                const strFileName = file!.name;
                const fileExtension = strFileName.substring(strFileName.lastIndexOf('.'));
                let fileName = uuid.v1() + fileExtension;
                const state = await uploadFile(file!, fileName);
                p.dataContent = JSON.stringify(
                    {
                        ...JSON.parse(p.dataContent),
                        remoteMediaUrl: getFile(fileName)
                    }
                )
                const str = localStorage.getItem("messages");
                if (str) {
                    let messages = JSON.parse(str);
                    const array = messages[`${conversations[current].targetId}`];
                    for (var item of array) {
                        if (item.fp == p.fp) {
                            item.dataContent = p.dataContent;
                        }
                    }
                    messages[`${conversations[current].targetId}`] = array;
                    dispatch(updateMessageImage({ message: messages }));
                }

            }


            IMSDK.sendData(p);


        }

    }


    const [isMounted, setIsMounted] = useState(false);


    useEffect(() => {
        setIsMounted(true);
    }, []);





    return (
        <div>
            <div className={`h-[540px] overflow-y-auto bg-gray-100 pt-3 `} style={{ opacity: isMounted ? 1 : 0, transition: 'opacity 1s' }} ref={listRef}>
                {loading && <div className="mt-2">正在加载...</div>}
                {
                    <MessageGroup messages={messages} conversation={conversation}></MessageGroup>
                }
            </div>
            <InputBox
                conversation={conversation}
                finshed={(text) => addMessage(text, MessageType.TxtMsg)}
                backFile={(file) => { addMessage("文件消息", MessageType.FileMsg, file) }}
                backVideo={(file) => { addMessage("文件消息", MessageType.SightMsg, file) }}
                backImage={(file) => { addMessage("文件消息", MessageType.ImgMsg, file) }}
            ></InputBox>
        </div>

    );
}



export const MessageGroup: React.FC<any> = ({ messages, conversation }) => {
    const messageGroups = [];
    let currentGroup: any = [];


    const isWithinFiveMinutes = (messageA: any, messageB: any) => {
        const fiveMinutesInMs: any = 3 * 60 * 1000;
        return Math.abs(new Date(messageA.timestamp).getTime() - new Date(messageB.timestamp).getTime()) <= fiveMinutesInMs;
    }


    if (messages) {
        messages.forEach((message: any, index: any) => {
            if (index === 0 || isWithinFiveMinutes(message, messages[index - 1])) {
                currentGroup.push(message);
            } else {
                // 当前组结束，添加到 messageGroups 并开始新组
                messageGroups.push(currentGroup);
                currentGroup = [message];
            }
        });
    }

    if (currentGroup.length > 0) {
        messageGroups.push(currentGroup);
    }



    return <div>
        {messageGroups.map((group, groupIndex) => (
            <div key={`${groupIndex}+messageGroups`}>
                <div className="text-gray-500">{formatTimestampWithWeekday(group[0].timestamp)}</div>
                {group.map((item: any, index: any) => (
                    <MessageItem key={`${item.fp}`} message={item} conversation={conversation} />
                ))}
            </div>
        ))}
    </div>
}